import React,{useState,useEffect} from 'react';
import DialogSimple from './DialogSimple' ; 
import {Table , Form} from 'react-bootstrap' ;

import Slider from 'react-rangeslider';
import 'react-rangeslider/lib/index.css' ;

import Select from 'react-select';
import dayjs from 'dayjs';
var esprima = require('esprima');
var escodegen = require('escodegen');

//props.isOpen
//props.onCancel
//props.lyrParams
//props.onOk
//props.gots
//props.appDateA
//props.appDateB
//props.isActiveGroupA
//props.loginedUser 
function DialogSimpleSDUI(props) {

    const [dialogTitle, setDialogTitle] = useState("SDUI");
    const [scriptObj, setScriptObj] = useState(null);
    const [sduiObject, setSduiObject] = useState(null);
	const [tempSliderValue, setTempSliderValue] = useState(0);
	const [sduiType, setSduiType] = useState(0);//0-none 1-layerSdui 2-gotsSdui
	const [gotsSubmitStateMessage, setGotsSubmitStateMessage] = useState("");

    //http get script content
	

    const httpGetScript =async function (scriptid) {
        const url = global.g_serverAPIRoot + "scripts/" +scriptid  ;
        return await fetch(url).then( response => response.json() )
            .then( (jsondata)=> {
                return jsondata.data ;
            }) ;
    }


	const httpGetGotsScriptAndUpdateUI = function(gots_sid){
		const url = global.g_serverAPIRoot + "scripts/" +gots_sid  ;

        fetch(url)
		.then( response => response.json() )
        .then( jsondata=> {
			const scriptText1 = jsondata.data.scriptContent ;
			const ast = esprima.parseScript(scriptText1);
			if( ast !== null && typeof(ast) !== undefined && ast.type==="Program"){
				for( const element of ast.body ){
					if( element.type === "VariableDeclaration" ){
						const decl = element.declarations[0] ;
						if( decl.type==="VariableDeclarator" ){
							if( decl.id.name === "sdui") {
								const initProperties = decl.init.properties ;
								const sduiCodePart = escodegen.generate(decl.init,{
									format:{
										newline:"",compact:true,
									}
								}) ;
								const tempObjectText = "JSON.stringify("+sduiCodePart+");" ;
								const tempObjectJsonStr = eval(tempObjectText) ;
								const tempSduiObject = JSON.parse(tempObjectJsonStr);
								setSduiObject(tempSduiObject) ;
								setSduiType(2) ;
							}
						}
					}
				}
			}
		}) ;

	}



    //reset title
    useEffect(() => {
		setGotsSubmitStateMessage("");
		setSduiObject({}) ;//clear
        if( props.lyrParams!==null && props.gots===null){
            setDialogTitle(props.lyrParams.productDisplay.productname + " SDUI") ;
			//检查 lyrParams 是否有sdui对象，如果sdui没有定义或者sdui等于null，则从网络加载，反之直接使用 lyrParams.sdui 
			if( typeof props.lyrParams.sdui === 'undefined' || props.lyrParams.sdui===null )
			{
				//load script text
				const paramsObj = JSON.parse(props.lyrParams.productDisplay.params) ;
				const scriptid = paramsObj.sid ;
				//http get
				httpGetScript(scriptid).then(
					(sObj)=>{
						setScriptObj(sObj) ;
						//javascript plain text
						const scriptText = sObj.scriptContent ;
						//parse AST
						const ast = esprima.parseScript(scriptText);
						if( ast !== null && typeof(ast) !== undefined && ast.type==="Program"){
							for( const element of ast.body ){
								if( element.type === "VariableDeclaration" ){
									const decl = element.declarations[0] ;
									if( decl.type==="VariableDeclarator" ){
										if( decl.id.name === "sdui") {
											const initProperties = decl.init.properties ;
											const sduiCodePart = escodegen.generate(decl.init,{
												format:{
													newline:"",compact:true,
												}
											}) ;
											const tempObjectText = "JSON.stringify("+sduiCodePart+");" ;
											const tempObjectJsonStr = eval(tempObjectText) ;
											const tempSduiObject = JSON.parse(tempObjectJsonStr);
											setSduiObject(tempSduiObject) ;
											setSduiType(1);
										}
									}
								}
							}
						}
					}
				)
			}
			else
			{
				setSduiObject(props.lyrParams.sdui) ;
				setSduiType(1);
			}
		}
		else if(props.lyrParams!==null && props.gots!==null){
			//GOTS 
			setDialogTitle(props.gots.metavalstr + " SDUI") ;
			httpGetGotsScriptAndUpdateUI(props.gots.metavali) ;
		}
		else{
            setDialogTitle("Null SDUI") ;
			setSduiType(0);
        }
    }, [props.lyrParams,props.gots]);
    

	// 滑动控件值变化
	const handleSliderChange = function( key , value) {
		let newObj = {... sduiObject} ;
		newObj[key].val = value ;
		setSduiObject(newObj);
	};

	const handleSliderNumberBoxChange = function(key,ev){
		let fval = parseFloat(ev.target.value) ;
		if( String(fval) === 'NaN' ) fval = 0 ;
		if( fval < sduiObject[key].valmin ) fval=sduiObject[key].valmin;
		if( fval > sduiObject[key].valmax ) fval=sduiObject[key].valmax;
		let newObj = {... sduiObject} ;
		newObj[key].val = fval ;
		setSduiObject(newObj);
	}

	// number组件值变化
	const handleNumberValueChange = function( key , value ){
		let newObj = {... sduiObject} ;
		newObj[key].val = value ;
		setSduiObject(newObj);
	}

	

	// select值变化
	const handleSelectValueChange = function( key , value ){
		let newObj = {... sduiObject} ;
		newObj[key].val= value ;
		setSduiObject(newObj);
	}

	// mselect
	const handleMSelectValueChange = function(key,newValue){
		let newObj = {... sduiObject} ;
		newObj[key].val= newValue ;
		setSduiObject(newObj);
	}



	// 渲染组件
	const renderUIComponent = function( key , obj ){
		
		if( obj.type==="number" ){
			return (
				<tr key={'key'+key}>
					<td>
					{obj.label}
					</td>
					<td>
					<Form.Control placeholder='' 
					type="number" 
					style={{width:'240px'}} 
					value={obj.val} 
					size="sm"
					onChange={(e)=>handleNumberValueChange(key,e.target.value)} />
					</td>
					<td></td>
				</tr>
			) ;
		}else if( obj.type==="select"){
			return (
				<tr key={'key'+key}>
					<td>
					{obj.label}
					</td>
					<td style={{textAlign:'left'}}>
						<select style={{width:'240px'}} value={obj.val} 
							onChange={(e)=>handleSelectValueChange(key,e.target.value)} >
							{
								obj.options.map((item,index)=>(
									<option key={'selkey'+index} value={item.val}>{item.text}</option>
								)) 
							}
						</select>
					</td>
					<td></td>
				</tr>
			);
		}else if( obj.type==="slider"){
			return (
				<tr key={'key'+key}>
					<td >
						{obj.label}
					</td>
					<td style={{width:"300px"}}>
						<Slider
						min={obj.valmin}
						max={obj.valmax}
						value={obj.val}
						onChange={(val)=>handleSliderChange(key,  val)}
						/>
					</td>
					<td >
						<Form.Control type='text' 
						size="sm"
						value={obj.val}
						onChange={(ev)=>handleSliderNumberBoxChange(key,ev)}
						/>
					</td>
				</tr>	
			) ;
		}
		else if(obj.type==='mselect'){
			return (
				<tr key={key}>
					<td>
					{obj.label}
					</td>
					<td style={{textAlign:'left',width:'400px'}}>
						<Select
						isMulti
						name={"mselect"+key}
						options={obj.options}
						className="basic-multi-select"
						onChange={(newValue)=>handleMSelectValueChange(key,newValue)}
						/>
					</td>
					<td></td>
				</tr>
			);
		}
		else{
			return "" ;
		}
	}


    //renderContent
    const renderContent = function () {

        return (
            <div style={{margin:'auto'}}>
				<Form style={{ textAlign: 'center' }}>
				<Table>
					<tbody>
						{ 
							( typeof sduiObject!=='undefined' && sduiObject!==null)?
							(
								Object.keys(sduiObject).map( (key) => renderUIComponent(key,sduiObject[key]) )
							):"" 
						}
					</tbody>
				</Table>
				</Form>
				<div>{gotsSubmitStateMessage}</div>
            </div>
        )
    }


	//js Date 对象转Long型 YYYYMMDD000000 数据，注意目前时分秒使用0代替。
	const convertJsDate2Ymd14 = function (jsDate) {
		const dayjsdate = dayjs(jsDate);
		const datetime1 = dayjsdate.format("YYYYMMDD000000");
		return datetime1;
	}


	//submit gots
	const httpSubmitGots = function(sduiObject) 
	{
		let dt = convertJsDate2Ymd14(props.appDateA) ;
		if(props.isActiveGroupA===false)dt = convertJsDate2Ymd14(props.appDateB) ;
		let uid=props.loginedUser.uid;
		let sduistr=JSON.stringify(sduiObject);
		let gotssid=props.gots.metavali;
		let url1=global.g_serverAPIRoot + "offtask/gots/new";
		let formdata = new FormData();
        formdata.append("dt", dt);
        formdata.append("uid", uid);
		formdata.append("sdui", sduistr);
		formdata.append("gotssid", gotssid);
        fetch(url1, {
            method: 'POST',
            body: formdata,
        })
		.then(response => response.json())
		.then(result => {
			if (result.state === 0) {
				setGotsSubmitStateMessage("任务请求已提交，您可以关闭对话框在离线任务面板查看任务状态和结果。");
				setGotsSubmitStateMessage("");
				setSduiObject({}) ;
				props.onCancel() ;
			}else{
				setGotsSubmitStateMessage("任务请求提交失败，错误:"+result.message);
			}
		}).catch(err => {
			setGotsSubmitStateMessage("任务请求提交失败，异常:"+err);
		});
	}

	//compress sduiObject
	const compressSduiObject = function(sduiobj){
		let sduiobj1 = {} ;
		for( let pptkey in sduiobj){
			sduiobj1[pptkey] = {} ;
			sduiobj1[pptkey].val = sduiobj[pptkey].val ;
		}
		return sduiobj1 ;
	}

	//is sduiObject ok
	const isSduiObjectEveryValOk = function(sduiobj){
		for( let pptkey in sduiobj){
			if( typeof sduiobj[pptkey].val==='undefined'
				|| sduiobj[pptkey].val === null 
				|| JSON.stringify(sduiobj[pptkey].val) === '{}' )
				{
					return false;
				}
		}
		return true ;
	}



	// onOk
	const onOk = function() {
		if( sduiType===1 )
		{
			props.onOk( props.lyrParams.displayid ,  sduiObject ) ;
		}
		else if( sduiType===2 ){
			
			//Gots
			// Add Post Request and wait to finished!
			// the OK button should be in loading, until task is finished.
			// if press cancel then , then do not track this task state,
			// user can view task state in offlinepanel.
			if( isSduiObjectEveryValOk(sduiObject) ===false )return ;
			let smallsdui = compressSduiObject(sduiObject);
			httpSubmitGots(smallsdui) ;
		}else{
			props.onOk( props.lyrParams.displayid ,  sduiObject ) ;
		}
		
	}

	//onCancel
	const onCancel = function () {
		setGotsSubmitStateMessage("");
		setSduiObject({}) ;
		props.onCancel() ;
	}

    return <DialogSimple isOpen={props.isOpen} onCancel={onCancel} dialogTitle={dialogTitle} onOk={onOk} renderContent={renderContent} />;
}

export default DialogSimpleSDUI;

